#!/usr/bin/env python3

# pacman -S icecat python python-selenium geckodriver


import time
from datetime import datetime
import code
import random
from os import path, environ
from selenium import webdriver
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
from selenium.webdriver.common.keys import Keys
from glob import glob


url = "https://crawl.kelbi.org"
lobby_read_delay = 10
interactive_mode = False
ignore_other_spectators = True


def tprint(string):
    print("[" + datetime.now().strftime("%Y-%m-%d %H:%M:%S") + "] " + string)

def determine_ff_profile():
    print('todo')
    # icecat --CreateProfile selenium
    # still need to disable all extensions / addons
    # to lauch the profile manually do $ icecat -P selenium

def get_server_list():
    print('todo')

def browser_and_profile(prefix='/usr/bin/'):
    ff_bin = None
    for exe in ['icecat', 'iceweasel', 'firefox']:
        if path.isfile(prefix + exe):
            ff_bin = exe
    if ff_bin == None:
        raise RuntimeError("no browser")
    ff_profile = glob(environ['HOME'] + '/.mozilla/' + ff_bin + '/*.selenium')[0]
    return (prefix + ff_bin, ff_profile)

def setup_webdriver(ff_bin_location, ff_profile_location):
    ffbin = FirefoxBinary(ff_bin_location)
    ffprofile = webdriver.FirefoxProfile(ff_profile_location)
    browser = webdriver.Firefox(ffprofile, firefox_binary=ffbin)
    return browser

def connect_to_lobby(browser, url, delay):
    browser.get(url)
    while True:
        time.sleep(delay)
        innerHTML = browser.execute_script("return document.body.innerHTML")
        if '<tr id="game-' in innerHTML:
            return innerHTML
        else:
            browser.refresh()


def connect_to_game(url, game_dict):
    browser.get('about:blank')
    tprint("Now watching: {} a {} playing {}".format(game_dict['username'], game_dict['race_class'], game_dict['game_version']))
    browser.get(url + '/' + game_dict['href'])
    time.sleep(5)
    browser.find_element_by_tag_name('body').send_keys(Keys.F12)

def go_fullscreen():
    browser.maximize_window()
    browser.fullscreen_window()

def save_html_to_file(filename):
    html = browser.execute_script("return document.body.innerHTML")
    outF = open(filename, "w")
    outF.writelines(html)
    outF.close()

def check_if_idle():
    print('todo')

def check_if_finished():
    print('todo')
    # the string "Morgue" isnt in during_gameplay.html
    # the string "Morgue is in game_completed.html


def parse_html_lobby_table(html):
    game_array = []
    html_player_table = html.split('<table id="player_list">')[1].split('</tbody>')[0].split('</tr>')[1:][:-1]
    for html_player_info in html_player_table:
        player_info = {}
        for line in html_player_info.splitlines():
            if '<tr id="game-' in line:
                player_info['id'] = line.split('"')[1]
            elif '<td class="username"><a href="#watch-' in line:
                player_info['href'] = line.split('"')[3]
                player_info['username'] = line.split('>')[2].split('<')[0]
            elif '<td class="game_id">' in line:
                player_info['game_version'] = line.split('>')[1].split('<')[0]
            elif '<td class="xl">' in line:
                player_info['xl'] = line.split('>')[1].split('<')[0]
            elif '<td class="char">' in line:
                player_info['race_class'] = line.split('>')[1].split('<')[0]
                #TODO: expand abreviations
            elif '<td class="place">' in line:
                player_info['place'] = line.split('>')[1].split('<')[0]
            elif '<td class="god">' in line:
                player_info['god'] = line.split('>')[1].split('<')[0]
            elif '<td class="idle_time" data-time="' in line:
                player_info['idle_time'] = line.split('"')[3]
            elif '<td class="spectator_count">' in line:
                player_info['spectator_count'] = line.split('>')[1].split('<')[0]
                if not player_info['spectator_count']:
                    player_info['spectator_count'] = '0'
            #TODO: milestone           
        if int(player_info['idle_time']) == 0:
            game_array.append(player_info)
    game_array = sorted(game_array, key=lambda k: k['spectator_count'], reverse=True)
    if (int(game_array[0]['spectator_count']) == 0) or (ignore_other_spectators):
        random.shuffle(game_array)
    return game_array

browser = setup_webdriver(*browser_and_profile())
lobby_html = connect_to_lobby(browser, url, lobby_read_delay)

#code.interact(local=locals())

go_fullscreen()
game_array = parse_html_lobby_table(lobby_html)
current_username = game_array[0]['username']
connect_to_game(url, game_array[0])

game_end_strings = ['The WebSocket connection failed', 'Morgue', 'Character dump']
current_html = browser.execute_script("return document.body.innerHTML")


if interactive_mode:
    code.interact(local=locals())
else:
    while True:
        time.sleep(30)
        last_html = current_html
        current_html = browser.execute_script("return document.body.innerHTML")
        game_array = parse_html_lobby_table(current_html)

        for str in game_end_strings:
            if str in current_html:
                # the game has finished, connect to a different game
                tprint("Gamed ended: found string {}".format(str))
                current_username = game_array[0]['username']
                connect_to_game(url, game_array[0])

        for game in game_array:
            if game['username'] == current_username:
                if int(game['idle_time']) > 0:
                    tprint("Gamed ended: timeout of {}".format(game['idle_time']))
                    # the player is idle, connect to a different game
                    current_username = game_array[0]['username']
                    connect_to_game(url, game_array[0])

        if last_html == current_html:
            # the game froze, probably due to network hiccup
            tprint("Gamed ended: not html change")
            current_username = game_array[0]['username']
            connect_to_game(url, game_array[0])

